#ifndef _audio_render_h_
#define _audio_render_h_
#include <mutex>
#include <ohaudio/native_audiorenderer.h>
#include <ohaudio/native_audiostreambuilder.h>
#include <queue>
#include <utility>

struct AudioFrameSlice {
    static void Deleter(void*);
    int64_t pts {0};
    std::shared_ptr<uint8_t> buffer {nullptr};
    int32_t bufferLen {0};
    int32_t bufferUsed {0};
};

class AudioRender {
public:
    AudioRender(int32_t sampleRate = 44100, int32_t channels = 2, \
                OH_AudioStream_SampleFormat sampleFormat = AUDIOSTREAM_SAMPLE_S16LE, int32_t bitWidth = 16);
    ~AudioRender();
    int32_t Init();
    int32_t Play();
    int32_t Pause();
    int32_t Resume();
    int32_t Flush();
    int32_t Stop();
    
    enum class PlayerState {
        NONE,
        INIT,
        RUNNING,
        PAUSE,
        STOP,
        RELEASE
    };
    
    int32_t PushFrameSlice(const AudioFrameSlice &frameSlice);
    AudioFrameSlice &FrontFrameSlice();
    int32_t PopFrameSlice();
    bool IsEmptyFrameSlice();
    bool CleanFrameSliceQueue();
    
    std::tuple<std::string, OH_AudioStream_SampleFormat, int32_t> &SampleFormat();
    int32_t SampleRate() const;
    int32_t Channels() const;
    
private:
    class RenderCallbacks {
        public:
        static int32_t OnWriteData(OH_AudioRenderer *render, void *userData, void *buffer, int32_t length);
    };

    PlayerState state_ {PlayerState::NONE};
    OH_AudioRenderer *audioRenderer_ {nullptr};
    OH_AudioStreamBuilder *audioStreamBuilder_ {nullptr};
    int32_t sampleRate_ {44100};
    int32_t channels_ {2};
    std::tuple<std::string, OH_AudioStream_SampleFormat, int32_t> sampleFormat_;
    mutable std::mutex queueMutex_;
    std::queue<AudioFrameSlice> frameQueue_;
};

#endif